// SPDX-FileCopyrightText: 2024 Amir <email>
// SPDX-License-Identifier: Apache-2.0

#include "event.h"



// Статические данные класса
bool *event::keys = nullptr;
unsigned int *event::frames = nullptr;
unsigned int event::_currentFrame = 0;
glm::dvec2 event::mouse_pos;
glm::dvec2 event::delta_mouse_move;


// что бы отследить нажатие на кнопку, мы создадим динамический массив который будет символизировать нажатие кнопки
void event::initialization() {
    event::keys = new bool[1032];
    event::frames = new unsigned int[1032];

    memset(event::keys, false, 1032 * sizeof(bool));
    memset(event::frames, 0, 1032 * sizeof(unsigned int));

    // регистрирование callbacks
    glfwSetKeyCallback(window::win, key_callback);
    glfwSetMouseButtonCallback(window::win, mouse_callback);

}

// ====================================================
// Отслеживания событий и обновление счётчика кадров
void event::pollEvents() {
    // переменные где будут храниться наша позиция курсора
    glm::dvec2 mpos;
    glfwGetCursorPos(window::win, &mpos.x, &mpos.y);

    // нахождение delta расстояния
    event::delta_mouse_move = mpos - event::mouse_pos;
    // после того как нашли delta расстояние, то можно присвоить временную переменную статической
    event::mouse_pos = mpos;

    // обновление счётчика кадров
    ++event::_currentFrame;
    glfwPollEvents();
}
// ====================================================

// очистка памяти
void event::finallyzation() {
    std::cout << "Очищение памяти системы" << std::endl;
    // delete pointers
    delete event::keys;
    delete event::frames;

    event::keys = nullptr;
    event::frames = nullptr;
}


// callback class event
bool event::isKeyPressed(int keycode) {
    return event::keys[keycode];
}


// одиночное нажатие
bool event::jKeyPressed(int keycode) {
    return event::keys[keycode] && event::frames[keycode] == event::_currentFrame;
}


// постоянное нажатие
bool event::isMousePressed(int keycode) {
    return event::keys[MOUSE_EVENT_BORDER + keycode];
}

// одиночное нажатие
bool event::jMousePressed(int keycode) {
    return event::keys[MOUSE_EVENT_BORDER + keycode] && event::frames[MOUSE_EVENT_BORDER + keycode] == event::_currentFrame;
}

const glm::dvec2& event::getMousePos() {
    return event::mouse_pos;
}

const glm::dvec2& event::getDeltaMouseMove() {
    return event::delta_mouse_move;
}




// callback key pressed
void event::key_callback(GLFWwindow *win, int key, int scancode, int action, int mods) {
    if(action == GLFW_PRESS) {
        event::keys[key] = true;
        event::frames[key] = _currentFrame;
    }
    else if(action == GLFW_RELEASE) {
        event::keys[key] = false;
    }
}


// callback mouse pressed
void event::mouse_callback(GLFWwindow *window, int button, int action, int mods) {
    if(action == GLFW_PRESS) {
        event::keys[MOUSE_EVENT_BORDER + button] = true;
        event::frames[MOUSE_EVENT_BORDER + button] = event::_currentFrame;
    }
    else if(action == GLFW_RELEASE) {
        event::keys[MOUSE_EVENT_BORDER + button] = false;
    }
}
